package com.luqili.utils.pub.pdf;

import com.luqili.utils.pub.graphical.LuPoint2D;
import org.apache.commons.lang3.StringUtils;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.font.PDFont;

import java.awt.*;
import java.io.IOException;
import java.util.List;

/**
 * 需要引入
 * <p>
 * org.apache.pdfbox-pdfbox:2.0.32
 *
 * @author luqili
 */
public class LuPdfBoxTool {
    /**
     * 头信息
     */
    public static final String PDF_CONTENT_TYPE = "application/pdf;charset=UTF-8";


    /**
     * 获取输入文本居中的起点
     *
     * @param text       文本内容
     * @param fontSize   指定打下
     * @param beginPoint 文本计算的始点
     * @param endPoint   文本计算的终点
     * @return 起点
     */
    public static LuPoint2D getTextCenterStartPoint(String text, PDFont font, float fontSize, LuPoint2D beginPoint, LuPoint2D endPoint) throws IOException {
        float textWidth = font.getStringWidth(text) * fontSize / 1000;
        float x = (endPoint.x - beginPoint.x - textWidth) / 2 + beginPoint.x;
        float y = (endPoint.y - beginPoint.y) / 2 + beginPoint.y;
        if (x < beginPoint.x) {
            x = beginPoint.x;
        }
        return new LuPoint2D(x, y);
    }

    /**
     * 文本居中显示的起点位置 X坐标
     *
     * @param text       输入文本
     * @param font
     * @param fontSize
     * @param beginPoint
     * @param endPoint
     * @return
     * @throws IOException
     */
    public static float getTextCenterStartPoint(String text, PDFont font, float fontSize, float beginPoint, float endPoint) throws IOException {
        float textWidth = font.getStringWidth(text) * fontSize / 1000;
        float x = (endPoint - beginPoint - textWidth) / 2 + beginPoint;
        if (x < beginPoint) {
            x = beginPoint;
        }
        return x;
    }


    /**
     * 指定位置，写入文本
     *
     * @param stream
     * @param text
     * @param font
     * @param fontSize
     * @param point
     * @throws IOException
     */
    public static void writeText(PDPageContentStream stream, String text, PDFont font, float fontSize, LuPoint2D point) throws IOException {
        if (StringUtils.isBlank(text)) {
            return;
        }
        stream.beginText();
        stream.setFont(font, fontSize);
        stream.newLineAtOffset(point.x, point.y);
        stream.showText(text);
        stream.endText();
    }

    /**
     * 该行平均分配为 texts.length 个空间，靠右写入文本
     *
     * @param stream
     * @param texts
     * @param font
     * @param fontSize
     * @param startPoint
     * @param endPoint
     * @throws IOException
     */
    public static void writeTexts(PDPageContentStream stream, List<String> texts, PDFont font, float fontSize, LuPoint2D startPoint, LuPoint2D endPoint) throws IOException {
        float widthX = endPoint.x - startPoint.x;
        float widthOne = widthX / texts.size();
        stream.setFont(font, fontSize);
        for (int i = 0; i < texts.size(); i++) {
            String text = texts.get(i);
            if (StringUtils.isNotBlank(text)) {
                stream.beginText();
                stream.newLineAtOffset(startPoint.x + widthOne * i, startPoint.y);
                stream.showText(text);
                stream.endText();
            }
        }
    }

    /**
     * 根据权重等信息设置字体
     *
     * @param stream
     * @param texts
     * @param startPoint
     * @param endPoint
     * @throws IOException
     */
    public static void writeTexts(PDPageContentStream stream, List<LuPDFTextInfo> texts, LuPoint2D startPoint, LuPoint2D endPoint) throws IOException {
        float widthX = endPoint.x - startPoint.x;
        int weight = 0;
        for (LuPDFTextInfo text : texts) {
            if (text.getWeight() != null && text.getWeight() > 0) {
                weight += text.getWeight();
            } else {
                weight++;
                text.setWeight(1);
            }
        }
        float widthOne = widthX / weight;

        float currentStartX = startPoint.x;
        for (int i = 0; i < texts.size(); i++) {
            LuPDFTextInfo text = texts.get(i);
            if (StringUtils.isNotBlank(text.getValue())) {
                if (text.getFont() != null) {
                    stream.setFont(text.getFont(), text.getSize());
                }
                stream.beginText();
                if (text.getColor() != null) {
                    stream.setNonStrokingColor(text.getColor());
                }
                stream.newLineAtOffset(currentStartX, startPoint.y);
                stream.showText(text.getValue());
                stream.endText();
            }
            currentStartX += widthOne * text.getWeight();
        }
    }

    /**
     * 居中写入文本
     *
     * @param stream
     * @param text
     * @param font
     * @param fontSize
     * @param startPoint
     * @param endPoint
     * @throws IOException
     */
    public static void writeTextCenter(PDPageContentStream stream, String text, PDFont font, float fontSize, LuPoint2D startPoint, LuPoint2D endPoint) throws IOException {
        stream.beginText();
        stream.setFont(font, fontSize);
        LuPoint2D point = LuPdfBoxTool.getTextCenterStartPoint(text, font, fontSize, startPoint, endPoint);
        stream.newLineAtOffset(point.x, startPoint.y);
        stream.showText(text);
        stream.endText();
    }

    /**
     * 画一条直线 实线
     *
     * @param stream
     * @param lineWidth
     * @param startPoint
     * @param endPoint
     * @throws IOException
     */
    public static void drawLine(PDPageContentStream stream, float lineWidth, LuPoint2D startPoint, LuPoint2D endPoint) throws IOException {
        stream.setLineWidth(lineWidth);
        stream.setLineCapStyle(0);
        stream.setLineJoinStyle(0);
        stream.moveTo(startPoint.x, startPoint.y);
        stream.lineTo(endPoint.x, endPoint.y);
        stream.stroke();
    }

    public static void drawLine(PDPageContentStream stream, float lineWidth, LuPoint2D startPoint, LuPoint2D endPoint, Color color) throws IOException {
        stream.setLineWidth(lineWidth);
        stream.setLineCapStyle(0);
        stream.setLineJoinStyle(0);
        stream.setStrokingColor(color);
        stream.moveTo(startPoint.x, startPoint.y);
        stream.lineTo(endPoint.x, endPoint.y);
        stream.stroke();
    }

    /**
     * 画一条直线 虚线
     *
     * @param stream
     * @param lineWidth  线的宽度
     * @param lineLength 间隔长度
     * @param startPoint 起点
     * @param endPoint   终点
     * @throws IOException
     */
    public static void drawLineDotted(PDPageContentStream stream, float lineWidth, float lineLength, LuPoint2D startPoint, LuPoint2D endPoint) throws IOException {
        stream.setLineWidth(lineWidth);
        stream.setLineCapStyle(1);
        stream.setLineJoinStyle(0);
        int count = (int) ((endPoint.x - startPoint.x) / lineLength);
        for (int i = 0; i < count + 1; i++) {
            if (i % 2 == 0) {
                float x1 = startPoint.x + lineLength * i;
                float x2 = startPoint.x + lineLength * (i + 1);
                if (x1 >= endPoint.x) {
                    continue;
                }
                if (x2 >= endPoint.x) {
                    x2 = endPoint.x;
                }
                stream.moveTo(x1, startPoint.y);
                stream.lineTo(x2, endPoint.y);
            }
        }
        stream.stroke();
    }


}
